home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / strategy / vga_card.000 / vga_cardgames-1.3.1.tar / vga_cardgames / solinux.c < prev    next >
C/C++ Source or Header  |  1995-02-26  |  11KB  |  482 lines

  1. /*
  2.  * Solitaire game (name unknown)
  3.  *
  4.  * Copyright (C) Evan Harris, 1994, 1995.
  5.  *
  6.  * Permission is granted to freely redistribute and modify this code,
  7.  * providing the author(s) get credit for having written it.
  8.  */
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <vga.h>
  13. #include <vgamouse.h>
  14.  
  15. #include "vga16.h"
  16. #include "mouse.h"
  17. #include "key.h"
  18. #include "solitaire.h"
  19.  
  20.  
  21. #define SO_SCREENMODE G640x480x16
  22. #define SO_SCREENWIDTH 640
  23. #define SO_SCREENHEIGHT 480
  24.  
  25. #define SO_TEXTFG 1
  26. #define SO_TEXTBG 0
  27. #define SO_BUTTONFG 2
  28. #define SO_BUTTONBG 6
  29. #define SO_MOUSEFG 5
  30. #define SO_MOUSEDARKFG 2
  31. #define SO_OUTLINE 6
  32.  
  33. #define NUMCARDIMAGES 52
  34. #define CARDACTUALWIDTH 53
  35. #define CARDIMAGEWIDTH 56
  36. #define CARDIMAGEHEIGHT 80
  37.  
  38. #define VERSION "SOLITAIRE\n  v1.3"
  39. #define VERSIONLEFT (SO_SCREENWIDTH - 76)
  40.  
  41. #ifndef CARDSFILE
  42. #define CARDSFILE "Cards56x80"
  43. #endif
  44. #ifndef CARDSMOUSESAMPLERATE
  45. #define CARDSMOUSESAMPLERATE MOUSE_DEFAULTSAMPLERATE
  46. #endif
  47.  
  48. #define USLEEP_TIME 30000
  49.  
  50.  
  51. #define CARDTOIMAGE(card)    (card % NUMCARDIMAGES)
  52.  
  53. #define BITWIDTH CARDIMAGEWIDTH /* multiple of 8 */
  54. #define BITHEIGHT CARDIMAGEHEIGHT
  55. #define BITSHOWLEFT 24        /* multiple of 8 */
  56. #define BITTOP 24
  57. #define COLWIDTH (BITWIDTH + 8)
  58. #define TOPROWHEIGHT    0
  59.  
  60.  
  61. #define SO_QUITLEFT (SO_SCREENWIDTH - 80)
  62. #define SO_QUITRIGHT (SO_QUITLEFT + 80)
  63. #define SO_QUITBOTTOM 132
  64. #define SO_QUITTOP (SO_QUITBOTTOM - 16)
  65.  
  66. #define SO_NEWGAMELEFT SO_QUITLEFT
  67. #define SO_NEWGAMERIGHT SO_QUITRIGHT
  68. #define SO_NEWGAMEBOTTOM 48
  69. #define SO_NEWGAMETOP (SO_NEWGAMEBOTTOM - 16)
  70.  
  71. #define SO_RESTARTLEFT SO_QUITLEFT
  72. #define SO_RESTARTRIGHT SO_QUITRIGHT
  73. #define SO_RESTARTBOTTOM 76
  74. #define SO_RESTARTTOP (SO_RESTARTBOTTOM - 16)
  75.  
  76. #define SO_UNDOLEFT SO_QUITLEFT
  77. #define SO_UNDORIGHT SO_QUITRIGHT
  78. #define SO_UNDOBOTTOM 104
  79. #define SO_UNDOTOP (SO_UNDOBOTTOM - 16)
  80.  
  81.  
  82. #define SO_PALETTESIZE 7
  83.  
  84. int palette[SO_PALETTESIZE * 3] = {
  85.     0x00, 0x20, 0x00,        /* green */
  86.     0x3f, 0x3f, 0x3f,        /* white */
  87.     0x00, 0x00, 0x00,        /* black */
  88.     0x37, 0x00, 0x00,        /* red */
  89.     0x00, 0x00, 0x20,        /* blue */
  90.     0x3f, 0x3f, 0x00,        /* yellow */
  91.     0x1a, 0x1a, 0x1a,        /* grey */
  92. };
  93.  
  94. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  95. static void LoadCards(char *file);
  96. static long GetMouseButton(void);
  97. static long WhileMouseButton(void);
  98. static int ParsePos(long pos, int downcard, int buttonup);
  99.  
  100. static unsigned char ***imageCard;
  101. static unsigned char **backCard;
  102. static unsigned char **outlineCard;
  103. static unsigned char *blankLine;
  104.  
  105.  
  106. void
  107. InitDisplay(int argc, char **argv)
  108. {
  109.     vga_disabledriverreport();
  110.     vga_init();
  111. #if !defined(CARDSMOUSE)
  112.     vga_setmousesupport(1);
  113. #endif
  114.     
  115.     if (vga_setmode(SO_SCREENMODE) != 0) {
  116.     fprintf(stderr, "Mode %s not available!\n",
  117.         vga_getmodename(SO_SCREENMODE));
  118.     exit(1);
  119.     }
  120.  
  121. #if defined(CARDSMOUSE)
  122.     mouse_init("/dev/mouse", vga_getmousetype(), CARDSMOUSESAMPLERATE);
  123.     mouse_setxrange(0, SO_SCREENWIDTH - 1);
  124.     mouse_setyrange(0, SO_SCREENHEIGHT - 1);
  125.     mouse_setwrap(MOUSE_NOWRAP);
  126. #endif
  127.  
  128.     vga16_init();
  129.  
  130.     LoadCards(CARDSFILE);
  131.  
  132.     blankLine = (unsigned char *)calloc(SO_SCREENWIDTH, sizeof(unsigned char));
  133.     if (blankLine == NULL) {
  134.     fprintf(stderr, "Error: cannot get memory for blankLine\n");
  135.     exit(1);
  136.     }
  137.  
  138.     vga_setpalvec(0, SO_PALETTESIZE, &palette[0]);
  139.  
  140.     vga16_text(SO_NEWGAMELEFT, SO_NEWGAMEBOTTOM, " NEW GAME ",
  141.            SO_BUTTONFG, SO_BUTTONBG);
  142.     vga16_text(SO_RESTARTLEFT, SO_RESTARTBOTTOM, " RESTART  ",
  143.            SO_BUTTONFG, SO_BUTTONBG);
  144.     vga16_text(SO_UNDOLEFT, SO_UNDOBOTTOM, "   UNDO   ",
  145.            SO_BUTTONFG, SO_BUTTONBG);
  146.     vga16_text(SO_QUITLEFT, SO_QUITBOTTOM, "   QUIT   ",
  147.            SO_BUTTONFG, SO_BUTTONBG);
  148.  
  149.     vga16_text(VERSIONLEFT, 200, VERSION, SO_TEXTFG, SO_TEXTBG);
  150. }
  151.  
  152.  
  153. static void
  154. LoadCards(char *file)
  155. {
  156.     int i, j, k, l, c, colour;
  157.     FILE *f;
  158.  
  159.     f = fopen(file, "r");
  160.     if (f == NULL) {
  161.     fprintf(stderr, "Cannot find '%s'\n", file);
  162.     exit(1);
  163.     }
  164.  
  165.     imageCard = (unsigned char ***)malloc(NUMCARDIMAGES
  166.                       * sizeof(unsigned char **));
  167.     if (imageCard == NULL) {
  168.     fprintf(stderr, "Error: cannot get memory for imageCard\n");
  169.     exit(1);
  170.     }
  171.     for (i = 0; i < NUMCARDIMAGES; i++) {
  172.     imageCard[i] = (unsigned char **)malloc(CARDIMAGEHEIGHT
  173.                         * sizeof(unsigned char *));
  174.     if (imageCard == NULL) {
  175.         fprintf(stderr, "Error: cannot get memory for imageCard[%d]\n",
  176.             i);
  177.         exit(1);
  178.     }
  179.     for (j = 0; j < CARDIMAGEHEIGHT; j++) {
  180.         imageCard[i][j] = (unsigned char *)malloc(CARDIMAGEWIDTH
  181.                               * sizeof(unsigned char));
  182.         if (imageCard[i][j] == NULL) { 
  183.         fprintf(stderr,
  184.             "Error: cannot get memory for imageCard[%d][%d]\n",
  185.             i, j);
  186.         exit(1);
  187.         }
  188.         
  189.         if (SUIT(i) == SPADES || SUIT(i) == CLUBS) {
  190.         colour = 2;
  191.         } else {
  192.         colour = 3;
  193.         }
  194.         if (TYPE(i) < JACK) {
  195.         for (k = 0; k < CARDIMAGEWIDTH / 8; k++) {
  196.             if ((c = getc(f)) == EOF) {
  197.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  198.             exit(1);
  199.             }
  200.             for (l = 0; l < 8; l++) {
  201.             imageCard[i][j][8 * k + l] =
  202.                 (c & 1 << (7 - l)) ? colour : 1;
  203.             }
  204.         }
  205.         for (k = CARDACTUALWIDTH; k < CARDIMAGEWIDTH; k++) {
  206.             imageCard[i][j][k] = 0;
  207.         }
  208.         } else {
  209.         for (k = 0; k < CARDIMAGEWIDTH / 2; k++) {
  210.             if ((c = getc(f)) == EOF) {
  211.             fprintf(stderr, "Unexpected EOF in '%s'\n", file);
  212.             exit(1);
  213.             }
  214.             imageCard[i][j][2 * k] = (unsigned char)c >> 4;
  215.             imageCard[i][j][2 * k + 1] = (unsigned char)c & 0xf;
  216.         }
  217.         }
  218.     }
  219.     }
  220.  
  221.     fclose(f);
  222.  
  223.     backCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
  224.     outlineCard = malloc(CARDIMAGEHEIGHT * sizeof(unsigned char *));
  225.     if (backCard == NULL || outlineCard == NULL) {
  226.     fprintf(stderr, "Error: cannot get memory for cards");
  227.     exit(1);
  228.     }
  229.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  230.     backCard[i] = malloc(CARDIMAGEWIDTH * sizeof(unsigned char));
  231.     outlineCard[i] = calloc(CARDIMAGEWIDTH, sizeof(unsigned char));
  232.     if (backCard[i] == NULL || outlineCard[i] == NULL) {
  233.         fprintf(stderr, "Error: cannot get memory for cards");
  234.         exit(1);
  235.     }
  236.     }
  237.     for (i = 0; i < CARDACTUALWIDTH; i++) {
  238.     outlineCard[0][i] = SO_OUTLINE;
  239.     outlineCard[CARDIMAGEHEIGHT - 1][i] = SO_OUTLINE;
  240.     }
  241.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  242.     outlineCard[i][0] = SO_OUTLINE;
  243.     outlineCard[i][CARDACTUALWIDTH - 1] = SO_OUTLINE;
  244.     }
  245.     for (i = 0; i < CARDIMAGEHEIGHT; i++) {
  246.     for (j = 0; j < CARDACTUALWIDTH; j++) {
  247.         if ((i / 4) % 2 == (j / 4) % 2) {
  248.         backCard[i][j] = 4;
  249.         } else {
  250.         backCard[i][j] = 1;
  251.         }
  252.     }
  253.     for (; j < CARDIMAGEWIDTH; j++) {
  254.         backCard[i][j] = 0;
  255.     }
  256.     }
  257. }
  258.  
  259.  
  260. static unsigned char columnTop[COLUMNS];
  261.  
  262. /* We redisplay a whole column, rather than do anything tricky. */
  263. void
  264. DisplayColumn(short col)
  265. {
  266.     unsigned char **image;
  267.     int card, length, row, height, line;
  268.     int bittop = BITTOP;
  269.     
  270.     for (card = column[col], length = 0; card != NOCARD; card = next[card])
  271.     length++;
  272.  
  273.     if (length > 0 && (SO_SCREENHEIGHT - TOPROWHEIGHT) / length < bittop)
  274.     bittop = (SO_SCREENHEIGHT - TOPROWHEIGHT) / length;
  275.     columnTop[col] = bittop;
  276.  
  277.     card = column[col];
  278.     row = TOPROWHEIGHT;
  279.     col = col * COLWIDTH;
  280.  
  281.     while (card != NOCARD && row < SO_SCREENHEIGHT - 1) {
  282.     if (hidden[card])
  283.         image = backCard;
  284.     else
  285.         image = imageCard[CARDTOIMAGE(card)];
  286.     if (next[card] == NOCARD)
  287.         height = BITHEIGHT;
  288.     else
  289.         height = bittop;
  290.     if (row + height >= SO_SCREENHEIGHT)
  291.         height -= row + height - SO_SCREENHEIGHT + 1;
  292.  
  293.     for (line = 0; line < height; line++) {
  294.         vga16_drawscansegment(image[line], col, row + line, BITWIDTH);
  295.     }
  296.  
  297.     row += height;
  298.     card = next[card];
  299.     }
  300.     for (; row < SO_SCREENHEIGHT; row++) {
  301.     vga16_drawscansegment(blankLine, col, row, BITWIDTH);
  302.     }
  303.  
  304.     return;
  305. }
  306.  
  307.  
  308. short
  309. GetCmd()
  310. {
  311.     int c, c1;
  312.     
  313.     for (c = NOCARD; c == NOCARD;) {
  314.     c = GetMouseButton();
  315.     c1 = WhileMouseButton();
  316.     if (c >= 0) {
  317.         c = ParsePos(c, -1, 0);
  318.         c1 = ParsePos(c1, c, 1);
  319.  
  320.         if (c == c1 && c >= 0) {
  321.         return c;
  322.         }
  323.         c = NOCARD;
  324.     }
  325.     }
  326.  
  327.     return c;
  328. }
  329.  
  330.  
  331. static int oldx = -1, oldy, oldcolour[40];
  332.  
  333. static long
  334. GetMouseButton()
  335. {
  336.     int x, y, button, key;
  337.  
  338.     x = mouse_getx();
  339.     y = mouse_gety();
  340.     if (x != oldx || y != oldy) {
  341.     if (oldx != -1) {
  342.         RestoreUnderMousePointer(oldx, oldy, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  343.     }
  344.     SaveUnderMousePointer(x, y, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  345.     RenderMousePointer(x, y, SO_MOUSEFG, SO_MOUSEDARKFG, SO_SCREENWIDTH, SO_SCREENHEIGHT);
  346.     oldx = x;
  347.     oldy = y;
  348.     }
  349.     
  350.     for (;;) {
  351.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  352.  
  353.     if (mouse_update()) {
  354.         x = mouse_getx();
  355.         y = mouse_gety();
  356.         button = mouse_getbutton();
  357.  
  358.         if (x != oldx || y != oldy) {
  359.         if (oldx != -1) {
  360.             RestoreUnderMousePointer(oldx, oldy, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  361.         }
  362.         SaveUnderMousePointer(x, y, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  363.         RenderMousePointer(x, y, SO_MOUSEFG, SO_MOUSEDARKFG, SO_SCREENWIDTH, SO_SCREENHEIGHT);
  364.         oldx = x;
  365.         oldy = y;
  366.         }
  367.     
  368.         if (button & MOUSE_LEFTBUTTON) {
  369.         break;
  370.         }
  371.     }
  372.     if ((key = key_getkey()) != -1) {
  373.         switch (key) {
  374.           case 'n':
  375.           case 'N':
  376.         return NEWGAME;
  377.           case 'r':
  378.           case 'R':
  379.         return RESTART;
  380.           case 'u':
  381.           case 'U':
  382.         return UNDO;
  383.           case 'q':
  384.           case 'Q':
  385.         return QUIT;
  386.           case '\014':
  387.         vga16_redrawscreen();
  388.         break;
  389.           default:
  390.         break;
  391.         }
  392.     }
  393.     }
  394.  
  395.     if (x >= SO_NEWGAMELEFT && x < SO_NEWGAMERIGHT
  396.     && y > SO_NEWGAMETOP && y <= SO_NEWGAMEBOTTOM) {
  397.     return NEWGAME;
  398.     }
  399.     if (x >= SO_RESTARTLEFT && x < SO_RESTARTRIGHT
  400.     && y > SO_RESTARTTOP && y <= SO_RESTARTBOTTOM) {
  401.     return RESTART;
  402.     }
  403.     if (x >= SO_UNDOLEFT && x < SO_UNDORIGHT
  404.     && y > SO_UNDOTOP && y <= SO_UNDOBOTTOM) {
  405.     return UNDO;
  406.     }
  407.     if (x >= SO_QUITLEFT && x < SO_QUITRIGHT
  408.     && y > SO_QUITTOP && y <= SO_QUITBOTTOM) {
  409.     return QUIT;
  410.     }
  411.  
  412.     return (x << 9) | y;
  413. }
  414.  
  415.  
  416. static long
  417. WhileMouseButton()
  418. {
  419.     int x, y, button;
  420.  
  421.     for (;;) {
  422.     usleep(USLEEP_TIME);    /* don't chew up as much CPU */
  423.  
  424.     mouse_update();
  425.     x = mouse_getx();
  426.     y = mouse_gety();
  427.     button = mouse_getbutton();
  428.  
  429.     if (x != oldx || y != oldy) {
  430.         if (oldx != -1) {
  431.         RestoreUnderMousePointer(oldx, oldy, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  432.         }
  433.         SaveUnderMousePointer(x, y, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  434.         RenderMousePointer(x, y, SO_MOUSEFG, SO_MOUSEDARKFG, SO_SCREENWIDTH, SO_SCREENHEIGHT);
  435.         oldx = x;
  436.         oldy = y;
  437.     }
  438.     
  439.     if (!(button & MOUSE_LEFTBUTTON)) {
  440.         break;
  441.     }
  442.     }
  443.  
  444.     if (oldx != -1) {
  445.     RestoreUnderMousePointer(oldx, oldy, SO_SCREENWIDTH, SO_SCREENHEIGHT, oldcolour);
  446.     }
  447.     oldx = -1;
  448.  
  449.     return (x << 9) | y;
  450. }
  451.  
  452.  
  453. static int
  454. ParsePos(long pos, int downcard, int buttonup)
  455. {
  456.     int x, y, card, row, bittop;
  457.     
  458.     x = pos >> 9;
  459.     y = pos & 0x1ff;
  460.     if (x / COLWIDTH > 6 || y < TOPROWHEIGHT ||
  461.     (x % COLWIDTH) / BITWIDTH > 0) {
  462.     return NOCARD;
  463.     }
  464.  
  465.     card = column[x / COLWIDTH];
  466.     bittop = columnTop[x / COLWIDTH];
  467.     row = TOPROWHEIGHT;
  468.  
  469.     while (card != NOCARD) {
  470.     if ((next[card] != NOCARD && y >= row && y < row + bittop)
  471.         || (next[card] == NOCARD && y >= row && y < row + BITHEIGHT)) {
  472.         if (!hidden[card] && (downcard == -1 || downcard == card)) {
  473.         return card;
  474.         }
  475.     }
  476.     card = next[card];
  477.     row += bittop;
  478.     }
  479.  
  480.     return NOCARD;
  481. }
  482.